from rest_framework import generics, status, permissions
from rest_framework.decorators import action
from rest_framework.response import Response
from rest_framework.viewsets import ModelViewSet
from django.utils import timezone
from django.db.models import Q
from .models import SystemMessage, MessageReadStatus
from .serializers import (
    SystemMessageSerializer, SystemMessageCreateSerializer,
    MessageReadStatusSerializer, UserMessageSerializer
)
from authentication.permissions import PermissionMixin


class SystemMessageViewSet(PermissionMixin, ModelViewSet):
    """
    系统消息管理ViewSet
    管理员可以CRUD系统消息
    """
    queryset = SystemMessage.objects.all()
    serializer_class = SystemMessageSerializer
    permission_classes = [permissions.IsAuthenticated]
    
    def get_serializer_class(self):
        if self.action == 'create':
            return SystemMessageCreateSerializer
        return SystemMessageSerializer
    
    def get_queryset(self):
        queryset = SystemMessage.objects.all()
        
        # 筛选参数
        priority = self.request.query_params.get('priority')
        is_active = self.request.query_params.get('is_active')
        search = self.request.query_params.get('search')
        
        if priority:
            queryset = queryset.filter(priority=priority)
        
        if is_active is not None:
            is_active_bool = is_active.lower() == 'true'
            queryset = queryset.filter(is_active=is_active_bool)
        
        if search:
            queryset = queryset.filter(
                Q(title__icontains=search) | Q(content__icontains=search)
            )
        
        return queryset.order_by('-created_at')
    
    def perform_create(self, serializer):
        # 检查权限
        if not self.has_permission('system.message.create'):
            self.permission_denied(self.request, '没有创建消息的权限')
        
        serializer.save(created_by=self.request.user)
    
    def perform_update(self, serializer):
        # 检查权限
        if not self.has_permission('system.message.update'):
            self.permission_denied(self.request, '没有更新消息的权限')
        
        serializer.save()
    
    def perform_destroy(self, instance):
        # 检查权限
        if not self.has_permission('system.message.delete'):
            self.permission_denied(self.request, '没有删除消息的权限')
        
        instance.delete()
    
    def list(self, request, *args, **kwargs):
        # 检查权限
        if not self.has_permission('system.message.list'):
            self.permission_denied(request, '没有查看消息列表的权限')
        
        return super().list(request, *args, **kwargs)


class UserMessageViewSet(ModelViewSet):
    """
    用户消息ViewSet
    普通用户查看自己的消息
    """
    serializer_class = UserMessageSerializer
    permission_classes = [permissions.IsAuthenticated]
    
    def get_queryset(self):
        user = self.request.user
        
        # 获取对用户可见的消息
        queryset = SystemMessage.objects.filter(
            is_active=True
        ).filter(
            Q(expire_at__isnull=True) | Q(expire_at__gt=timezone.now())
        )
        
        # 根据用户角色过滤
        user_roles = user.get_role_names()
        
        # 在Python中过滤消息，因为MySQL的JSON操作限制
        filtered_messages = []
        for message in queryset:
            # 没有设置目标角色的消息对所有用户可见
            if not message.target_roles:
                filtered_messages.append(message.id)
                continue
                
            # 检查用户角色是否在消息的目标角色中
            if user_roles and any(role in message.target_roles for role in user_roles):
                filtered_messages.append(message.id)
        
        # 根据过滤后的ID列表重新构建queryset
        queryset = queryset.filter(id__in=filtered_messages)
        
        # 筛选参数
        priority = self.request.query_params.get('priority')
        unread_only = self.request.query_params.get('unread_only')
        
        if priority:
            queryset = queryset.filter(priority=priority)
        
        if unread_only and unread_only.lower() == 'true':
            # 只显示未读消息
            read_message_ids = MessageReadStatus.objects.filter(
                user=user, message__in=queryset
            ).values_list('message_id', flat=True)
            queryset = queryset.exclude(id__in=read_message_ids)
        
        return queryset.order_by('-created_at')
    
    def list(self, request, *args, **kwargs):
        """获取消息列表"""
        return super().list(request, *args, **kwargs)
    
    def retrieve(self, request, *args, **kwargs):
        """获取单条消息详情"""
        return super().retrieve(request, *args, **kwargs)
    
    @action(detail=True, methods=['post'])
    def mark_read(self, request, pk=None):
        """标记消息为已读"""
        message = self.get_object()
        user = request.user
        
        # 创建或获取已读状态
        read_status, created = MessageReadStatus.objects.get_or_create(
            message=message,
            user=user
        )
        
        return Response({
            'message': '消息已标记为已读',
            'created': created
        }, status=status.HTTP_200_OK)
    
    @action(detail=False, methods=['post'])
    def mark_all_read(self, request):
        """批量标记所有消息为已读"""
        user = request.user
        messages = self.get_queryset()
        
        # 获取未读消息
        read_message_ids = MessageReadStatus.objects.filter(
            user=user, message__in=messages
        ).values_list('message_id', flat=True)
        
        unread_messages = messages.exclude(id__in=read_message_ids)
        
        # 批量创建已读状态
        read_statuses = [
            MessageReadStatus(message=message, user=user)
            for message in unread_messages
        ]
        
        created_count = len(read_statuses)
        if created_count > 0:
            MessageReadStatus.objects.bulk_create(read_statuses)
        
        return Response({
            'message': f'已标记 {created_count} 条消息为已读',
            'count': created_count
        }, status=status.HTTP_200_OK)
    
    @action(detail=False, methods=['get'])
    def unread_count(self, request):
        """获取未读消息数量"""
        user = request.user
        messages = self.get_queryset()
        
        # 计算未读数量
        read_message_ids = MessageReadStatus.objects.filter(
            user=user, message__in=messages
        ).values_list('message_id', flat=True)
        
        unread_count = messages.exclude(id__in=read_message_ids).count()
        
        return Response({
            'unread_count': unread_count
        }, status=status.HTTP_200_OK)